package com.jade.editor.domain.parts;

import java.io.File;
import java.io.FileFilter;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.HashMap;

import org.eclipse.core.runtime.IPath;
import org.eclipse.jface.dialogs.Dialog;
import org.eclipse.jface.dialogs.IDialogConstants;
import org.eclipse.jface.window.Window;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.graphics.RGB;
import org.eclipse.swt.widgets.ColorDialog;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.FileDialog;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.SWT;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Combo;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.events.MouseAdapter;
import org.eclipse.swt.events.MouseEvent;
import org.eclipse.wb.swt.SWTResourceManager;

import com.jade.logger.Logger;

public class SettingsBG extends Dialog {
	
	private IPath _filePath;
	private int _bgStatus = DrawArea.BACKGROUND_NONE;
	private RGB _color = null;
	private HashMap<String, File> _imgRoad = new HashMap<String, File>();
	private Point _size;
	private int _dist;
	private Point _imgLoc = new Point(0, 0);
	private boolean _imported = false;
	private String _importedName = "";
	private String _selectedImageName = null;
	

	/**
	 * Create the dialog.
	 * @param parentShell
	 */
	public SettingsBG(Shell parentShell, IPath filePath, int bgStatus, Point size, int dist, RGB bgColor, Point imgLocation, String selImgName) {
		super(parentShell);
		_filePath = filePath;
		_bgStatus = bgStatus;
		_size = size;
		_dist = dist;
		_color = bgColor;
		_imgLoc = imgLocation;
		_selectedImageName = selImgName;
	}
	
	protected void configureShell(Shell shell) {
		super.configureShell(shell);
		shell.setText("BG Settings");
	}
	
	public String getSelectedImageName(){
		if (_bgStatus == DrawArea.BACKGROUND_IMAGE)
			return _selectedImageName;
		return null;
	}
	
	public int getBGStatus(){
		return _bgStatus;
	}
	
	public RGB getBGColor(){
		return _color;
	}
	
	public Point getImgLocation(){
		return _imgLoc;
	}
	
	public File getBGImage(){
		return _imgRoad.get(_selectedImageName);
	}

	/**
	 * Create contents of the dialog.
	 * @param parent
	 */
	@Override
	protected Control createDialogArea(Composite parent) {
		final Composite container = (Composite) super.createDialogArea(parent);
		container.setLayout(null);
		
		final Button chkNone = new Button(container, SWT.RADIO);
		chkNone.setBounds(22, 10, 90, 16);
		chkNone.setText("None");
		
		final Button chkColor = new Button(container, SWT.RADIO);
		chkColor.setBounds(22, 40, 145, 16);
		chkColor.setText("Set Background Color");
		
		final Button chkImage = new Button(container, SWT.RADIO);
		chkImage.setBounds(22, 70, 145, 16);
		chkImage.setText("Set Background Image");
		
		Label separator1 = new Label(container, SWT.SEPARATOR | SWT.HORIZONTAL);
		separator1.setBounds(10, 32, 424, 2);
		
		//--------------------------
		final Composite compositeColor = new Composite(container, SWT.BORDER);
		compositeColor.setBounds(172, 37, 262, 19);
		
		final Label colorLabel = new Label(compositeColor, SWT.NONE);
		colorLabel.setBounds(75, 2, 117, 15);
		colorLabel.setText("Click to choose color");
		colorLabel.setBackground(SWTResourceManager.getColor(_color));
		compositeColor.setBackground(SWTResourceManager.getColor(_color));
		colorLabel.addMouseListener(new MouseAdapter() {
			@Override
			public void mouseUp(MouseEvent e) {
				ColorDialog cd = new ColorDialog(container.getShell());
				RGB tmpColor = colorLabel.getBackground().getRGB();
				_color = cd.open();
				if (_color != null){
					colorLabel.setBackground(SWTResourceManager.getColor(_color));
					compositeColor.setBackground(SWTResourceManager.getColor(_color));
				}
				else{
					_color = tmpColor;
				}
			}
		});
		compositeColor.addMouseListener(new MouseAdapter() {
			@Override
			public void mouseUp(MouseEvent e) {
				ColorDialog cd = new ColorDialog(container.getShell());
				RGB tmpColor = colorLabel.getBackground().getRGB();
				_color = cd.open();
				if (_color != null){
					colorLabel.setBackground(SWTResourceManager.getColor(_color));
					compositeColor.setBackground(SWTResourceManager.getColor(_color));
				}
				else{
					_color = tmpColor;
				}
			}
		});
		//---------------------------
		
		Label separator2 = new Label(container, SWT.SEPARATOR | SWT.HORIZONTAL);
		separator2.setBounds(10, 62, 424, 2);
		
		Label separator3 = new Label(container, SWT.SEPARATOR | SWT.HORIZONTAL);
		separator3.setBounds(10, 144, 424, 2);		final Button imgSettingsButton = new Button(container, SWT.NONE);
		imgSettingsButton.setText("Image Settings");
		imgSettingsButton.setBounds(22, 113, 145, 25);
		
		final Combo comboImg = new Combo(container, SWT.NONE);
		comboImg.setBounds(173, 70, 261, 23);
		
		final Button importImageButton = new Button(container, SWT.NONE);
		importImageButton.setBounds(319, 113, 115, 25);
		importImageButton.setText("Import new Image");
		
		//----------------
		
		if (_bgStatus == DrawArea.BACKGROUND_NONE){
			chkNone.setSelection(true);
			chkColor.setSelection(false);
			chkImage.setSelection(false);
			
			compositeColor.setEnabled(false);
			comboImg.setEnabled(false);
			imgSettingsButton.setEnabled(false);
			importImageButton.setEnabled(false);
		}
		else if (_bgStatus == DrawArea.BACKGROUND_COLOR){
			chkNone.setSelection(false);
			chkColor.setSelection(true);
			chkImage.setSelection(false);
			
			compositeColor.setEnabled(true);
			comboImg.setEnabled(false);
			imgSettingsButton.setEnabled(false);
			importImageButton.setEnabled(false);
		}
		else if (_bgStatus == DrawArea.BACKGROUND_IMAGE){
			chkNone.setSelection(false);
			chkColor.setSelection(false);
			chkImage.setSelection(true);
			
			compositeColor.setEnabled(false);
			comboImg.setEnabled(true);
			imgSettingsButton.setEnabled(true);
			importImageButton.setEnabled(true);
		}
		
		//--------------------------------
		chkNone.addSelectionListener(new SelectionAdapter() {
			@Override
			public void widgetSelected(SelectionEvent e) {
				_bgStatus = DrawArea.BACKGROUND_NONE;
				chkNone.setSelection(true);
				chkColor.setSelection(false);
				chkImage.setSelection(false);
				
				compositeColor.setEnabled(false);
				comboImg.setEnabled(false);
				imgSettingsButton.setEnabled(false);
				importImageButton.setEnabled(false);
			}
		});
		
		chkColor.addSelectionListener(new SelectionAdapter() {
			@Override
			public void widgetSelected(SelectionEvent e) {
				_bgStatus = DrawArea.BACKGROUND_COLOR;
				chkNone.setSelection(false);
				chkColor.setSelection(true);
				chkImage.setSelection(false);
				
				compositeColor.setEnabled(true);
				comboImg.setEnabled(false);
				imgSettingsButton.setEnabled(false);
				importImageButton.setEnabled(false);
			}
		});
		
		chkImage.addSelectionListener(new SelectionAdapter() {
			@Override
			public void widgetSelected(SelectionEvent e) {
				_bgStatus = DrawArea.BACKGROUND_IMAGE;
				chkNone.setSelection(false);
				chkColor.setSelection(false);
				chkImage.setSelection(true);
				
				compositeColor.setEnabled(false);
				comboImg.setEnabled(true);
				importImageButton.setEnabled(true);
				
				if (comboImg.getItemCount() > 0)
					imgSettingsButton.setEnabled(true);
			}
		});
		
		imgSettingsButton.addSelectionListener(new SelectionAdapter() {
			@Override
			public void widgetSelected(SelectionEvent e) {
				
				File img = _imgRoad.get(comboImg.getItem(comboImg.getSelectionIndex()));
				
				SettingsImage si = new SettingsImage(container.getShell(), _size, img, _dist, _imgLoc);
				si.open();
				
				if (si.getReturnCode() == Window.OK){
					_imgLoc = si.getImageLocation();
				}
				
				
			}
		});
		
		comboImg.addSelectionListener(new SelectionAdapter() {
			@Override
			public void widgetSelected(SelectionEvent e) {
				_selectedImageName = comboImg.getItem(comboImg.getSelectionIndex());
				_imgLoc = new Point(0,0);
			}
		});
		
		importImageButton.addSelectionListener(new SelectionAdapter() {
			@Override
			public void widgetSelected(SelectionEvent e) {
				
				FileDialog dlg = new FileDialog(importImageButton.getShell(), SWT.OPEN);
				dlg.setFilterNames(new String[] {
						"All Supported images (*.jpg, *.jpeg, *.bmp, *.png)",
						"Joint Photographic Experts Group Images (*.jpg, *.jpeg)",
						"Portable Network Graphics Images (*.png)",
						"Bitmap Picture (*.bmp)"
						});

				dlg.setFilterExtensions(new String[] {
						"*.jpg;*.jpeg;*.png;*.bmp",
						"*.jpg;*.jpeg",
						"*.png",
						"*.bmp"
						});
				String fileName = dlg.open();
				if (fileName != null) {
					String dir = new File(_filePath.toFile().getParentFile().getParent() + "\\Pictures").toString();
					if (!picDirExists())
						createPicFolder();
					if(!copyFileToWithNoOverwrite(fileName, dir)){
						Logger.print(Logger.STATE_ERROR, "Image Import Error (File already exists or permission deny)");
					}
					else{
						
						fillImageData(comboImg);
					}
				}
				
			}
		});
		
		fillImageData(comboImg);
		
		if (comboImg.getItemCount() > 0 && _bgStatus == DrawArea.BACKGROUND_IMAGE)
			imgSettingsButton.setEnabled(true);
		else
			imgSettingsButton.setEnabled(false);
		
		return container;
	}

	/**
	 * Create contents of the button bar.
	 * @param parent
	 */
	@Override
	protected void createButtonsForButtonBar(Composite parent) {
		createButton(parent, IDialogConstants.OK_ID, IDialogConstants.OK_LABEL, true);
		createButton(parent, IDialogConstants.CANCEL_ID, IDialogConstants.CANCEL_LABEL, false);
	}

	/**
	 * Return the initial size of the dialog.
	 */
	@Override
	protected Point getInitialSize() {
		return new Point(450, 236);
	}
	
	private void fillImageData(Combo combo){
		combo.removeAll();
		_imgRoad.clear();
		
		if (picDirExists()){
			File imgDir = new File(_filePath.toFile().getParentFile().getParent() + "\\Pictures");
			
			FileFilter ffJPG = new FileFilter(){
				@Override
				public boolean accept(File f) {
					if (f.getName().toLowerCase().endsWith("jpg"))
						return true;
					if (f.getName().toLowerCase().endsWith("jpeg"))
						return true;
					if (f.getName().toLowerCase().endsWith("bmp"))
						return true;
					if (f.getName().toLowerCase().endsWith("png"))
						return true;
					return false;
				}
			};
			
			for(File img : imgDir.listFiles(ffJPG)){
				combo.add(img.getName());
				_imgRoad.put(img.getName(), img);
			}
			
			if (combo.getItemCount() > 0){
				if(_imported){
					for(int i = 0; i < combo.getItemCount(); i++){
						if(combo.getItem(i).equals(_importedName)){
							combo.select(i);
							break;
						}
					}
				}
				
				if(!_imported && _selectedImageName != null){
					for(int i = 0; i < combo.getItemCount(); i++){
						if(combo.getItem(i).equals(_selectedImageName)){
							combo.select(i);
							break;
						}
					}
				}
				
				
				
				if(!_imported && _selectedImageName == null){
					combo.select(0);
					_selectedImageName = combo.getItem(combo.getSelectionIndex());
				}
					
				
				
			}
				
		}
		else{
			System.out.println("Picture directory does not exist!");
		}
	}
	
	
	private boolean picDirExists(){
		File imgDir = new File(_filePath.toFile().getParentFile().getParent() + "\\Pictures");
		if (imgDir.exists())
			return true;
		return false;
	}
	
	
	private void createPicFolder(){
		new File(_filePath.toFile().getParentFile().getParent() + "\\Pictures").mkdir();
	}
	
	
	private boolean copyFileToWithNoOverwrite(String filePath, String dirPath){
		File file = new File(filePath);
		File dir = new File(dirPath + "//" + file.getName());
		
		if (dir.exists()) return true;
		
		try {
			InputStream in = new FileInputStream(file);
			OutputStream out = new FileOutputStream(dir);
			
			byte[] buf = new byte[1024];
			int len;
			try {
				while ((len = in.read(buf)) > 0){
					out.write(buf, 0, len);
				}
			} catch (IOException e) {
				e.printStackTrace();
				return false;
			}
			try {
				in.close();
				out.close();
			} catch (IOException e) {
				e.printStackTrace();
				return false;
			}
			
		} catch (FileNotFoundException e) {
			e.printStackTrace();
			return false;
		}
		
		_imported = true;
		_importedName = file.getName();
		
		return true;
	}
}
